#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#define M 31
#define HASHNUMBER 29989

class Hashnode
{
public:
  char* _word;   //the word to be stored.
  int count;     //the number of the word.
   Hashnode* next;
   Hashnode(){next = NULL;};
   Hashnode(char *word){strcpy(_word,word);count = 1;next = NULL;};
   ~Hashnode(){};
};

Hashnode* hashlist[HASHNUMBER] = {NULL};//hash list
//Hash function
unsigned int hashindex( char* word)
{
  unsigned int index = 0;
   for(; *word != '\0'; word++)
     {
       index = M*index + *word;
     }
   return index % HASHNUMBER; 
}

int insertword(char *word)
{
  char *m;
  int num;
  num = strlen(word);              // transforming the majuscule to lowercase
  m = (char *)malloc(strlen(word)+1);
  for(; *word != '\0'; word++)
    if(*word >= 'A' && *word <= 'Z')
      {*m = *word + 32;m++;}
    else {*m = *word;m++;}
  *m = '\0';
  m = m - num;
   Hashnode *p;
   unsigned int index = hashindex(m);
   for(p = hashlist[index];p != NULL;p = p->next)
     {
       if(strcmp(m,p->_word) == 0){(p->count)++;return 0;}
     }
   p = (Hashnode *)malloc(sizeof(Hashnode));
   p->count = 1;
   p->_word = (char *)malloc(strlen(word)+1);
   strcpy(p->_word,m);
   p->next = hashlist[index];
   hashlist[index] = p;
   return 0;
}
void readtext(const char* path)
{
  FILE *fp;
  char buf[1024];
  char *p;
  char *delimit;
  delimit = " ][,\t\n.:!?\"";  //the division sign

  fp = fopen(path,"r");
  if(fp == NULL){std::cout <<"open file error!\n";exit(-1);}
  while(fgets(buf,sizeof(buf),fp)!=NULL)
    {  buf[strlen(buf)-1] = '\0';
      if(strcmp("",buf) == 0) continue;
      p = strtok(buf,delimit);
	 while(p != NULL)
	   {  insertword(p);
	    p = strtok(NULL,delimit);
	   }
    }
      fclose(fp);
}

void freehashlist()
{
  int i;
  Hashnode *p,*q;
  p = q = NULL;
  for(i = 0;i < HASHNUMBER;i++)
    {
      p = hashlist[i];
      while(p != NULL){q = p; p = p->next;delete q;}
    }
}

int main(int argc, char *argv[])
{
   readtext("alibaba.txt");
   unsigned int index;
   Hashnode* p;
   std::cout <<"the whole text's word:" << std::endl; 
   for(index = 0;hashlist[index] != NULL,index < HASHNUMBER;index++)
    for(p = hashlist[index];p != NULL; p = p->next)
   {
     std::cout <<  p->_word << " " << p->count << "\n";
   }

   std::cout << "the number of word is a litter more:" << std::endl;
    for(index = 0;hashlist[index] != NULL,index < HASHNUMBER;index++)
    for(p = hashlist[index];p != NULL; p = p->next)
   {
     if((p->count) >= 12)
     std::cout << p->_word << " " << p->count << std::endl;
   }
   return 0;
}











